package com.xiaobias.stuy;

import org.junit.Test;

import java.nio.charset.StandardCharsets;
import java.sql.SQLOutput;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * @author lw
 * @since 2023/6/20-08:16
 */
public class OptionalTest {

    @Test
    public void test() {
        // optional 是什么，如何用
        Optional<Student> optional = Optional.of(new Student());
        Optional<Student> optional1 = Optional.ofNullable(new Student());
        Optional<Object> empty = Optional.empty();

        // optional 实际使用
        // 避免 NPE
        // 打印学生姓名
        Student student = new Student("李四", "30", 100);
        if (student != null) {
            String theStudent = student.getName();
            System.out.println("一般方法：" + theStudent);
        }

        // 常见的"错误"用法
        Optional<Student> optionalStudent = Optional.ofNullable(student);
        if (optional.isPresent()) {
            Student theStudent = optionalStudent.get();
            System.out.println("optional 错误用法 = " + theStudent.getName());
        }

        // 正确用法
        optionalStudent.map(Student::getName).ifPresent(System.out::println);


        // 如果存在做点什么
        optionalStudent.ifPresent(this::callOther);

        // 过滤
        optional.filter(st -> st.getScore() > 10).ifPresent(st ->System.out.println("age > 10 " + st.getName()));

        // orElse 和 orElseGet 的区别
        optional.orElse(createStudent());
        optional.orElseGet(this::createStudent);

        // map 和 flatMap
        optional.flatMap(this::getStudentName);
        optional.map(this::getStudentName);

        List<Student> students = Arrays.asList(
                new Student("李四", "100", 100),
                new Student("张伟", "99", 99),
                new Student("王小姐", "88", 88),
                new Student("贝果", "77", 77)
        );
        // Java8之前的判断
        for (Student st : students) {
            if (st != null) {
                if (st.getAge().equals("99")) {
                    Integer score = st.getScore();
                    if (score != null && score >= 50) {
                        System.out.println("入选学生 " + st.getName());
                    }
                }
            }
        }
        // java8 使用 optional
        for (Student st : students) {
            Optional<Student> studentOptional = Optional.of(st);
            Integer score = studentOptional
                    .filter(s -> s.getAge().equals("88"))
                    .map(Student::getScore)
                    .orElse(0);
            if (score > 50) {
                System.out.println("入选的学生 " + st.getName());
            }
        }


    }

    private Student createStudent() {
        System.out.println("called from createStudent");
        return new Student();
    }

    private Optional<String> getStudentName(Student student) {
        return Optional.ofNullable(student).map(Student::getName);
    }

    private Object callOther(Student s) {
        System.out.printf("call other %s...", s);
        return null;
    }
}

class Student {
   private String name;
   private String age;
   private Integer score;

    public Student() {
    }

    public Student(String name, String age, Integer score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
        this.score = score;
    }
}
